package com.hy.lightning.boot;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.EnumSet;
import java.util.Properties;

import javax.servlet.DispatcherType;

import org.apache.log4j.PropertyConfigurator;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

import com.hy.lightning.boot.core.ServicesFactory;
import com.hy.lightning.boot.service.Boot;
import com.hy.lightning.boot.web.filter.BaseFilter;
import com.hy.lightning.boot.web.filter.FilterHandler;
import com.hy.lightning.boot.web.listener.BaseListener;
import com.hy.lightning.boot.web.listener.ListenerHandler;
import com.hy.lightning.boot.web.servlet.ServletMapper;
import com.hy.lightning.commons.utils.ObjectUtil;

/**
 * 服务启动类
 * 
 * @author root
 *
 */
public class JettyServer {

	public static Properties serverInitContext = new Properties();

	private static int server_port = 9999;

	private static String contextPath = "/";

	private static ListenerHandler listenerHandler;

	private static FilterHandler filterHandler;

	private static Class<?>[] clesses;

	static {
		initLog4j();
	}
	
	public static void main(String[] args) throws FileNotFoundException, IOException, InstantiationException,
			IllegalAccessException, ClassNotFoundException {
		if (args != null && args.length >= 1 && args[0].endsWith("boot.properties")) {
			run(args[0]);
		} else {
			clesses = new Class[args.length];
			for(int i = 0; i < args.length; i++) {
				clesses[i] = Class.forName(args[i]);
			}
			run(null);
		}
	}

	public static void run() throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException {
		run("conf/boot.properties");
	}
	
	public static void run(String boot_properties)
			throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
		InputStream boot_properties_in = null;
		File file = null;
		if(boot_properties != null)
			file = new File(System.getProperty("user.dir") + File.separator + boot_properties);
		if (boot_properties == null || !file.exists()) {
			boot_properties_in = ClassLoader.getSystemResourceAsStream("com/hy/lightning/boot/conf/boot.properties");
		} else {
			String project_conf = System.getProperty("user.dir") + File.separator + boot_properties;
			boot_properties_in = new FileInputStream(project_conf);
		}
		serverInitContext.load(boot_properties_in);
		if (serverInitContext.containsKey("server_port"))
			server_port = Integer.valueOf(serverInitContext.getProperty("server_port"));
		if (serverInitContext.containsKey("contextPath"))
			contextPath = serverInitContext.getProperty("contextPath");
		if (serverInitContext.containsKey("listenerHandler")) {
			String listenerHandlerClassPath = serverInitContext.getProperty("listenerHandler");
			listenerHandler = (ListenerHandler) Class.forName(listenerHandlerClassPath).newInstance();
		}
		if (serverInitContext.containsKey("filterHandler")) {
			String filterHandlerClassPath = serverInitContext.getProperty("filterHandler");
			filterHandler = (FilterHandler) Class.forName(filterHandlerClassPath).newInstance();
		}
		if (serverInitContext.containsKey("services_classPaths")) {
			String[] services_classPaths = serverInitContext.getProperty("services_classPaths").split(",");
			clesses = new Class[services_classPaths.length];
			for (int i = 0; i < services_classPaths.length; i++) {
				String classPath = services_classPaths[i];
				clesses[i] = Class.forName(classPath);
			}
		}
		run(server_port, contextPath, listenerHandler, filterHandler, clesses);
	}

	public static void run(int port, String contextPath, ListenerHandler listenerHandler, FilterHandler filterHandler,
			Class<?>... services) {
		initLog4j();
		ServicesFactory.loadService(Boot.class);
		if (services != null && services.length >= 1)
			ServicesFactory.loadService(services);

		ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
		if (ObjectUtil.isNullOrEmpty(contextPath))
			contextPath = "/";
		servletContextHandler.setContextPath(contextPath);

		// 添加Listener
		servletContextHandler.addEventListener(new BaseListener(listenerHandler));

		// 添加filter
		servletContextHandler.addFilter(new FilterHolder(new BaseFilter(filterHandler)), "/*",
				EnumSet.of(DispatcherType.REQUEST));

		// 添加servlet
		servletContextHandler.addServlet(new ServletHolder(new ServletMapper()), "/");

		// 创建Server对象，并绑定端口
		Server server = new Server(port);
		server.setHandler(servletContextHandler);
		try {
			server.start();
			server.join();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void initLog4j() {
		String log_dir = System.getProperty("user.dir") + "/logs/".replace("/", File.separator);
		System.setProperty("log.dir", log_dir);
		PropertyConfigurator
				.configure(ClassLoader.getSystemResourceAsStream("com/hy/lightning/boot/conf/log4j.properties"));
	}
}
